﻿using EmbeddedSensorCloud.HTTP;
using EmbeddedSensorCloud.Plugin.StaticFile.Properties;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Linq;

namespace EmbeddedSensorCloud.Plugin.StaticFile
{
    public sealed class Program : IPlugin
    {
        // File caching (5MB)
        private const int maxCacheSize = 1024 * 1024 * 5;
        private int currentCacheSize = 0;
        private Dictionary<string, byte[]> fileCache;
        
        private string wwwDir;

        public bool IsResponseable(Request request)
        {
            if (string.IsNullOrEmpty(request.Url))
            {
                return false;
            }

            string fullPath = getFullPath(request.Url);
            return File.Exists(fullPath) && MIMEAssistant.GetMIMEType(fullPath) != null;
        }

        private string getFullPath(string url)
        {
            // adds index.html if path is just '/'
            if (url.EndsWith("/"))
            {
                url += "/index.html";
            }

            try
            {
                return Path.Combine(wwwDir, url.Substring(1));
            }
            catch
            {
                return string.Empty;
            }
        }

        public Response Respond(Request request)
        {
            string fullPath = getFullPath(request.Url);
            string contentType = MIMEAssistant.GetMIMEType(fullPath);

            Response response = new Response();
            response.Headers["Content-Type"] = contentType;

            if (fileCache.ContainsKey(request.Url))
            {
                response.Body = fileCache[request.Url];
            }
            else
            {
                response.Body = File.ReadAllBytes(fullPath);
                int newCacheSize = currentCacheSize + response.Body.Length;

                if (newCacheSize < maxCacheSize)
                {
                    fileCache.Add(request.Url, response.Body);
                    currentCacheSize = newCacheSize;
                }
            }
            return response;
        }

        public Program(string wwwDirectory)
        {
            this.fileCache = new Dictionary<string, byte[]>();
            this.wwwDir = wwwDirectory;
        }

        public void Initialize()
        {
            if (!Directory.Exists(this.wwwDir))
            {
                throw new DirectoryNotFoundException("Invalid www directory!");
            }
        }
    }
}
